﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using FlexminAPI;

namespace FlexLib.Plugins
{
	public class Plugin
	{
		AppDomain domain;
		Assembly assembly;

		Type masterType = null;
		public Type MasterType
		{
			get { return masterType; }
		}

		Type slaveType = null;
		public Type SlaveType
		{
			get { return slaveType; }
		}

		IMaster master = null;
		public IMaster Master
		{
			get
			{
				if (master == null)
					if (masterType != null)
						master = assembly.CreateInstance(masterType.FullName) as IMaster;

				return master;
			}
		}

		ISlave slave = null;
		public ISlave Slave
		{
			get
			{
				if (slave == null)
					if (slaveType != null)
						slave = assembly.CreateInstance(slaveType.FullName) as ISlave;

				return slave;
			}
		}

		Type GetMasterType(Assembly assembly)
		{
			foreach (Type type in assembly.GetTypes())
				if (type.IsSubclassOf(typeof(IMaster)))
				{
					return type;
				}

			return null;
		}

		Type GetSlaveType(Assembly assembly)
		{
			foreach (Type type in assembly.GetTypes())
				if (type.IsSubclassOf(typeof(ISlave)))
				{
						return type;
				}

			return null;
		}

		PluginInfo info;

		public PluginInfo Info
		{
			get { return info; }
		}

		public Plugin(PluginInfo info, string assemblyPath)
		{
			this.info = info;

/*			string pluginDirectory = Path.GetDirectoryName(assemblyPath);
			AppDomainSetup domainSetup = new AppDomainSetup();
			domainSetup.ApplicationName = assemblyPath;
			domainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
			domainSetup.CachePath = Path.Combine(pluginDirectory, "cache" + Path.DirectorySeparatorChar);
			domainSetup.ShadowCopyFiles = "true";
			domainSetup.ShadowCopyDirectories = pluginDirectory;

			domain = AppDomain.CreateDomain(
				assemblyPath, null, domainSetup);
*/
//			domain = AppDomain.CreateDomain(assemblyPath);
//			assembly = domain.Load(AssemblyName.GetAssemblyName(assemblyPath));
			assembly = Assembly.LoadFrom(assemblyPath);

			masterType = GetMasterType(assembly);
			slaveType = GetSlaveType(assembly);

			if (masterType == null && slaveType == null)
				throw new Exception("No master, no slave type found.");
		}

		public void Unload()
		{
//			AppDomain.Unload(domain);
		}
	}
}
